package cc.rome753.wat;

import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;

import org.json.JSONObject;
import org.webrtc.AudioProcessingFactory;
import org.webrtc.AudioSource;
import org.webrtc.AudioTrack;
import org.webrtc.Camera1Enumerator;
import org.webrtc.DefaultVideoDecoderFactory;
import org.webrtc.DefaultVideoEncoderFactory;
import org.webrtc.EglBase;
import org.webrtc.IceCandidate;
import org.webrtc.MediaConstraints;
import org.webrtc.MediaStream;
import org.webrtc.PeerConnection;
import org.webrtc.PeerConnectionFactory;
import org.webrtc.SessionDescription;
import org.webrtc.SurfaceTextureHelper;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoSource;
import org.webrtc.VideoTrack;
import org.webrtc.audio.JavaAudioDeviceModule;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MainActivity extends AppCompatActivity implements SignalingClient.Callback, View.OnClickListener {

    private SurfaceViewRenderer localView;
    private SurfaceViewRenderer[] remoteViews;

    private Button btnRecordVideo;
    private Button btnRecordAudio;
    private Button btnPlayVideo;
    private Button btnPlayAudio;

    private WebrtcClient webrtcClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnRecordVideo = findViewById(R.id.btn_toggle_record_video);
        btnRecordVideo.setOnClickListener(this);
        btnRecordAudio = findViewById(R.id.btn_toggle_record_audio);
        btnRecordAudio.setOnClickListener(this);
        btnPlayVideo = findViewById(R.id.btn_toggle_play_video);
        btnPlayVideo.setOnClickListener(this);
        btnPlayAudio = findViewById(R.id.btn_toggle_play_audio);
        btnPlayAudio.setOnClickListener(this);

        webrtcClient = new WebrtcClient(this);

        localView = findViewById(R.id.localView);
        webrtcClient.setLocalView(localView);

        remoteViews = new SurfaceViewRenderer[]{
                findViewById(R.id.remoteView),
                findViewById(R.id.remoteView2),
                findViewById(R.id.remoteView3),
        };
        for(SurfaceViewRenderer remoteView : remoteViews) {
            webrtcClient.addRemoteView(remoteView);
        }

        SignalingClient.get().init(this);

        if (!PermissionUtil.isMediaPermissionsGranted(this)) {
            PermissionUtil.gotoSettings(this, true);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        SignalingClient.get().destroy();
        if (webrtcClient != null) {
            webrtcClient.release();
        }
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();
        switch (id) {
            case R.id.btn_toggle_record_video:
                toggleRecordVideo();
                break;
            case R.id.btn_toggle_record_audio:
                toggleRecordAudio();
                break;
            case R.id.btn_toggle_play_video:
                togglePlayVideo();
                break;
            case R.id.btn_toggle_play_audio:
                togglePlayAudio();
                break;
        }
    }

    @Override
    public void onCreateRoom() {

    }

    @Override
    public void onPeerJoined(String socketId) {
        PeerConnection peerConnection = webrtcClient.getOrCreatePeerConnection(socketId);
        peerConnection.createOffer(new SdpAdapter("createOfferSdp:" + socketId) {
            @Override
            public void onCreateSuccess(SessionDescription sessionDescription) {
                super.onCreateSuccess(sessionDescription);
                peerConnection.setLocalDescription(new SdpAdapter("setLocalSdp:" + socketId), sessionDescription);
                SignalingClient.get().sendSessionDescription(sessionDescription, socketId);
            }
        }, new MediaConstraints());
    }

    @Override
    public void onSelfJoined() {

    }

    @Override
    public void onPeerLeave(String msg) {

    }

    @Override
    public void onOfferReceived(JSONObject data) {
        runOnUiThread(() -> {
            final String socketId = data.optString("from");
            PeerConnection peerConnection = webrtcClient.getOrCreatePeerConnection(socketId);
            peerConnection.setRemoteDescription(new SdpAdapter("setRemoteSdp:" + socketId),
                    new SessionDescription(SessionDescription.Type.OFFER, data.optString("sdp")));
            peerConnection.createAnswer(new SdpAdapter("localAnswerSdp") {
                @Override
                public void onCreateSuccess(SessionDescription sdp) {
                    super.onCreateSuccess(sdp);
                    webrtcClient.getOrCreatePeerConnection(socketId).setLocalDescription(new SdpAdapter("setLocalSdp:" + socketId), sdp);
                    SignalingClient.get().sendSessionDescription(sdp, socketId);
                }
            }, new MediaConstraints());

        });
    }

    @Override
    public void onAnswerReceived(JSONObject data) {
        String socketId = data.optString("from");
        PeerConnection peerConnection = webrtcClient.getOrCreatePeerConnection(socketId);
        peerConnection.setRemoteDescription(new SdpAdapter("setRemoteSdp:" + socketId),
                new SessionDescription(SessionDescription.Type.ANSWER, data.optString("sdp")));
    }

    @Override
    public void onIceCandidateReceived(JSONObject data) {
        String socketId = data.optString("from");
        PeerConnection peerConnection = webrtcClient.getOrCreatePeerConnection(socketId);
        peerConnection.addIceCandidate(new IceCandidate(
                data.optString("id"),
                data.optInt("label"),
                data.optString("candidate")
        ));
    }

    public void toggleRecordVideo() {
        if (webrtcClient.isRecordVideoFlag()) {
            btnRecordVideo.setText("start record video");
            webrtcClient.setRecordVideoFlag(false);
        } else {
            btnRecordVideo.setText("stop record video");
            webrtcClient.setRecordVideoFlag(true);
        }
    }

    public void toggleRecordAudio() {
        if (webrtcClient.isRecordAudioFlag()) {
            btnRecordAudio.setText("start record audio");
            webrtcClient.setRecordAudioFlag(false);
        } else {
            btnRecordAudio.setText("stop record audio");
            webrtcClient.setRecordAudioFlag(true);
        }
    }

    public void togglePlayVideo() {
        if (webrtcClient.isPlayVideoFlag()) {
            btnPlayVideo.setText("start play video");
            webrtcClient.setPlayVideoFlag(false);
        } else {
            btnPlayVideo.setText("stop play video");
            webrtcClient.setPlayVideoFlag(true);
        }
    }

    public void togglePlayAudio() {
        if (webrtcClient.isPlayAudioFlag()) {
            btnPlayVideo.setText("start play audio");
            webrtcClient.setPlayAudioFlag(false);
        } else {
            btnPlayVideo.setText("stop play audio");
            webrtcClient.setPlayAudioFlag(true);
        }
    }
}
